﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using GPainter.Interfaces;
using GPainter.Layout;

namespace GPainter.ModelViewPresenter
{
    //хранилище графа
    [Serializable]
    public class Model
    {
        public List<IEdgeData> Edges { get; set; }//коллекция ребер
        public List<INodeData> Nodes { get; set; }//коллекция вершин

        public Model()
        {
            Edges = new List<IEdgeData>();
            Nodes = new List<INodeData>();
        }

        #region Сериализация/Десериализация 

        public void Save(string FileName)//сериализация графа
        {
            var xmlFormatter = new XmlSerializer(typeof(Model),
                new[] { typeof(List<IEdgeData>), typeof(List<INodeData>), typeof(IEdgeData), typeof(INodeData) });
            var FStream = new FileStream(FileName, FileMode.Create, FileAccess.Write);
            try
            {
                xmlFormatter.Serialize(FStream, this);
            }
            catch 
            {
               MessageBox.Show("Невозможно сохранить в файл!!!", "Ошибка", MessageBoxButton.OK, 
                   MessageBoxImage.Error);
                
            }
            finally
            {
                if (FStream != null) FStream.Close();
            }
        }
        public Model Load(string FileName)//десериализация графа
        {
            XmlSerializer xmlFormatter = new XmlSerializer(typeof(Model),
                new Type[] { typeof(List<IEdgeData>), typeof(List<INodeData>), typeof(IEdgeData), typeof(INodeData) });
            FileStream FStream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
            try
            {
                return (Model)xmlFormatter.Deserialize(FStream);
            }
            catch
            {
                MessageBox.Show("Невозможно загрузить из файла!!!", "Ошибка", MessageBoxButton.OK, 
                    MessageBoxImage.Error);
            }
            finally
            {
                if (FStream != null) FStream.Close();
               
            }
            return null;
        }

        #endregion 

        public void AddNode(INodeData n)//добавление вершины
        {
            Nodes.Add(n);
        }
        public void DeleteNode(INodeData n)//удаление вершины
        {
            Nodes.Remove(n);
        }
        public void AddEdge(IEdgeData e)//добавление ребра
        {
            Edges.Add(e);
        }
        public void DeleteEdge(IEdgeData e)//удаление ребра
        {
            Edges.Remove(e);
        }
        public INodeData GetNode(string id)//получение вершины по иденту
        {
            return Nodes.Find(
                n => n.Id == id);
        }
        public IEdgeData GetEdge(string id)//получение ребра по иденту
        {
            return Edges.Find(
                e => e.Id == id);
        }
        public IEdgeData FindEdge(string sNode, string tNode, string edgeText)
        {
            return Edges.FirstOrDefault(e => (e.SourceNode == sNode) && (e.TargetNode == tNode) && (e.EdgeText == edgeText));
        }

        //автоматическая укладка на плоскости
        public void AutomaticLayout()
        {
            //инициализируем ГА
            planarGA GA = new planarGA(Nodes, Edges);
            //получаем коллекцию вершин с новыми координатами точек
            Nodes = GA.CalculateLayout();
           
        }
        
    }
}
